<template>
  <!-- 'z-index': `${place === 0 ? cardId : ''}`, -->
  <div
    class="card-icon-container"
    :style="{
      width: `${cardSize}px`,
      height: `${cardSize}px`,
      background: `${bg || !infoStore.isColor || iconBg}`,
      border: `2px solid ${borColor}`,
      position: `${place === 0 ? 'absolute' : ''}`,
      left: `${(coor.x * cardSize) / 2}px`,
      top: `${(coor.y * cardSize) / 2}px`,
      'border-radius': `${borRadius}px`,
      'z-index': cardId,
    }"
    @click="handleClick"
  >
    <i
      :class="icon"
      :style="{
        color: `${color || !infoStore.isColor || iconColor}`,
        'font-size': `${cardSize * 0.6}px`,
      }"
    ></i>
  </div>
</template>

<script>
import voice1 from "@/assets/audio/clickVoice/5.mp3"; // 使用卡片的音效
import voice2 from "@/assets/audio/clearVoice/1.mp3"; // 卡片消除的音效
import getRandom from "@/utils/getRandom";
export default {
  props: {
    // 卡片id
    cardId: {
      type: Number,
      required: true,
    },
    // 卡片尺寸
    cardSize: {
      type: Number,
      required: true,
    },
    // 卡片所在区域 [0: 游戏区, 1: 卡槽区]
    place: {
      type: Number,
      default: 0,
    },
    // 卡片坐标
    coor: {
      type: Object,
      default: () => ({ x: 0, y: 0 }),
    },
    // 图标id
    iconId: {
      type: Number,
      default: 0,
    },
    // 图标颜色
    color: {
      type: String,
      // default: "#000",
    },
    // 背景色
    bg: {
      type: String,
      // default: "#fff",
    },
    // 边框色
    borColor: {
      type: String,
      // default: "#ccc",
    },
    // 圆角
    borRadius: {
      type: Number,
      default: 8,
    },
  },
  data() {
    return {
      infoStore: this.$store.state.info,
      cardStore: this.$store.state.cards,
      icon: this.$store.state.cards.cardData[this.iconId].className, // 图标的class
      iconColor: this.$store.state.cards.cardData[this.iconId].color, // 图标的字体颜色
      iconBg: this.$store.state.cards.cardData[this.iconId].bg, // 图标的背景颜色
    };
  },
  methods: {
    handleClick() {
      if (this.infoStore.isBanCardClick) {
        // 禁止点击卡片
        return;
      }
      if (this.place === 1) {
        // 若点击的是卡槽的卡片
        // 如果可消除 ['下载']
        if (this.cardStore.isSlotDelete) {
          const slotCards = this.infoStore.slotCards;
          for (let i = 0; i < slotCards.length; i++) {
            if (slotCards[i].cardId === this.cardId) {
              // 找到点击的卡片
              this.playVoice(voice2);
              this.$store.commit("info/deleteSlotCard", i);
              this.$store.commit("cards/setIsSlotDelete", false);
              console.log("成功消除卡槽中的一张卡片");
              return;
            }
          }
        }
        // 如果可增加 ['照相机']
        if (this.cardStore.isSlotAdd) {
          const slotCards = this.infoStore.slotCards;
          for (let i = 0; i < slotCards.length; i++) {
            const card = slotCards[i];
            if (card.cardId === this.cardId) {
              // 找到点击的卡片
              this.playVoice(voice1);
              const coor = {
                x: getRandom(0, this.infoStore.size.w - 1),
                y: getRandom(0, this.infoStore.size.h - 1),
              };
              this.$store.commit("cards/setIsSlotAdd", false); // 设置为不可增加卡槽卡片
              console.log("成功复制卡槽中的一张卡片");
              // 抛出成功点击事件
              this.$bus.$emit("successClick", {
                cardData: {
                  cardId: this.infoStore.cardId,
                  iconId: card.iconId,
                  coor,
                },
              });
              this.$store.commit("info/setCardId", this.infoStore.cardId + 1);
              return;
            }
          }
        }
      } else if (this.place === 2) {
        // console.log(this.iconId);
        // 若点击的是卡片池的卡片
        switch (this.iconId) {
          case 0: // 铅笔
            if (
              !this.infoStore.isBanCardClick &&
              this.cardStore.cardData[0].useNum &&
              this.infoStore.isStarted &&
              typeof this.cardStore.myCards.find((item) => item === 0) ===
                "number"
            ) {
              this.startCode(0, false, this.cardStore.cardData[0].useNum - 1);
              this.$store.commit("cards/setIsEdit", true); // 设置可修改卡片
            }
            break;
          case 1: // 垃圾箱
            if (
              !this.infoStore.isBanCardClick &&
              this.cardStore.cardData[1].useNum &&
              this.infoStore.isStarted &&
              this.cardStore.myCards.find((item) => item === 1)
            ) {
              this.startCode(1, true, this.cardStore.cardData[1].useNum - 1); // 播放使用卡片的音效, 将该卡片的使用次数-1
              const cards = this.infoStore.gameCards; // 获取包含所有卡片的详细数据的数组, 每个卡片都有这些数据, cardId: 卡片id(同时也是表示卡片所在的z轴的坐标(高度)), iconId: 卡片图标的id, coor: 卡片在卡片区的坐标
              if (cards.length <= 5) { // 如果卡片区剩余的卡片小于等于5张(清楚后一定会胜利)
                this.$bus.$emit("gameWin"); // 抛出游戏胜利的事件, 让其他组件能够知道游戏已经胜利了, xxxxxxx.$emit就是抛出一个事件让其他组件监听到(让他们知道发生了这个事情)
                console.log("成功消除" + cards.length + "张卡片"); // 在控制台打印一句话(控制台的内容页面看不见,这句可以不理会)
                return; // 直接结束, 后面的代码不运行了, 因为游戏已经结束了, 不需要再实现这个卡片的效果了(其他组件中监听到了游戏胜利这个事件后会执行某些函数, 其中就有清空卡片区卡片的这个效果, 所以这里后面的代码可以不执行)
              }
              for (let i = 0; i < 5; i++) { // 循环5次, 每次删除一张卡片
                this.$store.commit( // 删除仓库中的卡片区(游戏区)所有卡片的数组中的一项, deleteGameCard这个方法需要传入删除的卡片在数组中的索引
                  "info/deleteGameCard",
                  getRandom(0, cards.length - 1) // 随机生成一个0-max的索引
                );
              }
              console.log("成功消除5张卡片"); // 打印消息到控制台
            }
            break;
          case 2: // 电话
            if (
              !this.infoStore.isBanCardClick &&
              this.cardStore.cardData[2].useNum &&
              this.infoStore.isStarted &&
              this.cardStore.myCards.find((item) => item === 2)
            ) {
              this.startCode(2, true, this.cardStore.cardData[2].useNum - 1);
              const cards = this.infoStore.gameCards;
              const clearCard = this.infoStore.clearCard;
              let count = 0;
              if (cards.length <= clearCard) {
                this.$bus.$emit("gameWin");
                console.log("成功消除" + cards.length + "张相同卡片");
                return;
              }
              const iconId = cards[getRandom(0, cards.length - 1)].iconId;
              for (let i = cards.length - 1; i >= 0; i--) {
                const card = cards[i];
                if (card.iconId === iconId) {
                  this.$store.commit("info/deleteGameCard", i);
                  count++;
                  if (clearCard === count) {
                    console.log("成功消除" + count + "张相同卡片");
                    return;
                  }
                }
              }
            }
            break;
          case 3: // 购物袋
            if (
              !this.infoStore.isBanCardClick &&
              this.cardStore.cardData[3].useNum &&
              this.infoStore.isStarted &&
              this.cardStore.myCards.find((item) => item === 3)
            ) {
              this.startCode(3, false, this.cardStore.cardData[3].useNum - 1);
              this.$store.commit("cards/setIsDelete", true);
            }
            break;
          case 4: // 感叹号
            if (
              !this.infoStore.isBanCardClick &&
              this.cardStore.cardData[4].useNum &&
              this.infoStore.isStarted &&
              this.cardStore.myCards.find((item) => item === 4)
            ) {
              this.startCode(4, true, this.cardStore.cardData[4].useNum - 1);
              const cards = this.infoStore.gameCards;
              const resultArr = []; // 可点击的卡片组 [存入gameCards索引]
              // 找到全部可点击[顶部]的卡片
              cards.forEach((item, i) => {
                if (this.isCardClick(item)) {
                  resultArr.push(i);
                }
              });
              resultArr.forEach((item) => {
                this.$store.commit("info/setGameCardIcon", {
                  i: item,
                  iconId: 4,
                }); // 设为感叹号
              });
              console.log("成功替换顶层卡片为'感叹号'");
            }
            break;
          case 5: // 放大镜
            if (
              !this.infoStore.isBanCardClick &&
              this.cardStore.cardData[5].useNum &&
              this.infoStore.isStarted &&
              this.cardStore.myCards.find((item) => item === 5)
            ) {
              this.startCode(5, false, this.cardStore.cardData[5].useNum - 1);
              this.$store.commit("cards/setIsCover", false);
            }
            break;
          case 6: // 下载
            if (
              !this.infoStore.isBanCardClick &&
              this.cardStore.cardData[6].useNum &&
              this.infoStore.isStarted &&
              this.cardStore.myCards.find((item) => item === 6)
            ) {
              this.startCode(6, false, this.cardStore.cardData[6].useNum - 1);
              this.$store.commit("cards/setIsSlotDelete", true);
            }
            break;
          case 7: // 照相机
            if (
              !this.infoStore.isBanCardClick &&
              this.cardStore.cardData[7].useNum &&
              this.infoStore.isStarted &&
              this.cardStore.myCards.find((item) => item === 7)
            ) {
              this.startCode(7, false, this.cardStore.cardData[7].useNum - 1);
              this.$store.commit("cards/setIsSlotAdd", true);
            }
            break;
          case 8: // 录像机
            if (
              !this.infoStore.isBanCardClick &&
              this.cardStore.cardData[8].useNum &&
              this.infoStore.isStarted &&
              this.cardStore.myCards.find((item) => item === 8)
            ) {
              this.startCode(8, true, this.cardStore.cardData[8].useNum - 1);
              const cards = this.infoStore.slotCards; // 卡槽的卡片
              let oldCoor = { x: -1, y: -1 };
              cards.forEach((item) => {
                const card = item;
                const coor = {
                  x: getRandom(0, this.infoStore.size.w - 1, [oldCoor.x]),
                  y: getRandom(0, this.infoStore.size.h - 1, [oldCoor.y]),
                };
                // 将卡片加入游戏中
                this.$store.commit("info/addGameCard", {
                  cardId: this.infoStore.cardId,
                  iconId: card.iconId,
                  coor,
                });
                this.$store.commit("info/setCardId", this.infoStore.cardId + 1); // id+1
                oldCoor = coor;
              });
              this.$store.commit("info/deleteSlotCard", -1); // 清空卡槽
              console.log("成功回退卡槽中所有卡片");
            }
            break;
          case 9: // 铃铛
            if (
              !this.infoStore.isBanCardClick &&
              this.cardStore.cardData[9].useNum &&
              this.infoStore.isStarted &&
              this.cardStore.myCards.find((item) => item === 9)
            ) {
              this.startCode(9, true, this.cardStore.cardData[9].useNum - 1);
              const cards = this.infoStore.gameCards;
              const curCardArr = [cards[0], cards[1], cards[2]]; // 记录第1,2,3张卡片
              curCardArr.forEach((item, i) => {
                this.$store.commit("info/deleteGameCard", i); // 删除第0,1,2张卡片
                this.$store.commit("info/addGameCard", {
                  cardId: this.infoStore.cardId,
                  iconId: curCardArr[i].iconId,
                  coor: {
                    x: curCardArr[i].coor.x,
                    y: curCardArr[i].coor.y,
                  },
                }); // 将卡片重新加入
                this.$store.commit("info/setCardId", this.infoStore.cardId + 1);
              });
              console.log("成功将最底层的3张卡片置于顶层");
            }
            break;
          case 10: // 加载
            if (
              !this.infoStore.isBanCardClick &&
              this.cardStore.cardData[10].useNum &&
              this.infoStore.isStarted &&
              this.cardStore.myCards.find((item) => item === 10)
            ) {
              this.startCode(10, true, this.cardStore.cardData[10].useNum - 1);
              let oldCoor = { x: -1, y: -1 };
              this.infoStore.gameCards.forEach((item, i) => {
                const coor = {
                  // 生成与前一个卡片不同的坐标
                  x: getRandom(0, this.infoStore.size.w - 1, [oldCoor.x]),
                  y: getRandom(0, this.infoStore.size.h - 1, [oldCoor.y]),
                };
                oldCoor = coor;
                this.$store.commit("info/setGameCardCoor", { i, coor });
                console.log("刷新卡片位置");
              });
            }
            break;
          case 11: // 文本
            if (this.cardStore.myCards.find((item) => item === 11)) {
              if (this.cardStore.isShowCurCard) {
                // 关闭显示
                this.$bus.$emit("clickCardPool", true);
                this.$store.commit("cards/setIsShowCurCard", false);
              } else {
                // 显示
                this.playVoice(voice1);
                this.$bus.$emit("clickCardPool", true);
                this.$store.commit("cards/setIsShowCurCard", true);
              }
            }
            break;
          case 12: // 电脑
            if (
              !this.infoStore.isBanCardClick &&
              this.cardStore.cardData[12].useNum &&
              this.infoStore.isStarted &&
              this.cardStore.myCards.find((item) => item === 12)
            ) {
              this.startCode(12, true, this.cardStore.cardData[12].useNum - 1);
              const cards = this.infoStore.gameCards;
              const resultArr = []; // 可点击的卡片组 [存入gameCards索引]
              // 找到全部可点击[顶部]的卡片
              cards.forEach((item, i) => {
                if (this.isCardClick(item)) {
                  resultArr.push(i);
                }
              });
              // 倒序删除
              for (let i = resultArr.length - 1; i >= 0; i--) {
                this.$store.commit("info/deleteGameCard", resultArr[i]);
              }
              if (this.infoStore.gameCards.length === 0) {
                // 胜利
                this.$bus.$emit("gameWin");
              }
              console.log("成功消除顶层所有卡片");
            }
            break;
          case 13: // 剪刀
            if (
              !this.infoStore.isBanCardClick &&
              this.cardStore.cardData[13].useNum &&
              this.infoStore.isStarted &&
              this.cardStore.myCards.find((item) => item === 13)
            ) {
              this.startCode(13, false, this.cardStore.cardData[13].useNum - 1);
              this.$store.commit("cards/setIsDeleteArea", true);
            }
            break;
          case 14: // 消息
            if (
              !this.infoStore.isBanCardClick &&
              this.cardStore.cardData[14].useNum &&
              this.infoStore.isLevelMode &&
              this.cardStore.myCards.find((item) => item === 14)
            ) {
              this.startCode(14, false, this.cardStore.cardData[14].useNum - 1);
              if (this.cardStore.levelNum <= 4) {
                if (this.cardStore.isPass) {
                  this.playVoice(voice1);
                  this.$store.commit("cards/setIsCanRanking", false); // 关卡时间数据无效 [不能上榜]
                  this.$store.commit("cards/setIsPass", false);
                  this.$store.commit("info/gameReset");
                  console.log("成功跳过关卡");
                  this.$bus.$emit("gameWin");
                } else {
                  // 弹窗
                  this.$message({
                    showClose: true,
                    message: "次数已用尽, 通过第5关后才会刷新呢",
                    type: "success",
                    duration: 3500,
                    offset: this.infoStore.popOffset,
                  });
                }
              } else {
                // 弹窗
                this.$message({
                  showClose: true,
                  message: "只有在前4关时候才能使用哦",
                  type: "warning",
                  duration: 3500,
                  offset: this.infoStore.popOffset,
                });
              }
            }
            break;
          case 15: // 下雨
            if (
              !this.infoStore.isBanCardClick &&
              this.cardStore.cardData[15].useNum &&
              this.infoStore.isStarted &&
              this.cardStore.myCards.find((item) => item === 15)
            ) {
              this.startCode(15, true, this.cardStore.cardData[15].useNum - 1);
              const slot = this.infoStore.slotCards;
              slot.forEach((item, i) => {
                this.$store.commit("info/setSlotCardIcon", { i, iconId: 15 }); // 设置卡槽中卡片的iconId
              });
              console.log("成功设置卡槽卡片为'雨'");
            }
            break;
          case 16: // 双向
            if (
              !this.infoStore.isBanCardClick &&
              this.cardStore.cardData[16].useNum &&
              this.infoStore.isStarted &&
              this.cardStore.myCards.find((item) => item === 16)
            ) {
              this.startCode(16, true, this.cardStore.cardData[16].useNum - 1);
              const slot = this.infoStore.slotCards;
              const resultArr = [];
              let num = [];
              for (let i = 0; i < slot.length - 1; i++) {
                num = [i];
                for (let j = i + 1; j < slot.length; j++) {
                  if (j !== i && slot[j].iconId === slot[i].iconId) {
                    num.push([j]);
                  }
                }
                if (num.length === 2) {
                  resultArr.push(num[0]);
                  resultArr.push(num[1]);
                }
              }
              // 倒删
              for (let i = resultArr.length - 1; i >= 0; i--) {
                this.$store.commit("info/deleteSlotCard", resultArr[i]);
              }
              console.log("成功删除卡槽中所有数量为2的卡片");
            }
            break;
          case 17: // 樱桃
            if (
              !this.infoStore.isBanCardClick &&
              this.cardStore.cardData[17].useNum &&
              this.infoStore.isStarted &&
              this.cardStore.myCards.find((item) => item === 17)
            ) {
              this.startCode(17, true, this.cardStore.cardData[17].useNum - 1);
              const resultArr = []; // 樱桃的数组
              const cards = this.infoStore.gameCards;
              cards.forEach((item, i) => {
                if (item.iconId === 17) {
                  resultArr.push(i);
                }
              });
              for (let i = resultArr.length - 1; i >= 0; i--) {
                this.$store.commit("info/deleteGameCard", resultArr[i]);
              }
            }
            break;
          default:
            break;
        }
      }

      // console.log("点击一次");
      const cardData = {
        cardId: this.cardId,
        iconId: this.iconId,
        coor: this.coor,
      };
      // 抛出事件
      this.$bus.$emit("gameCardClick", cardData); // 向事件总线中抛出事件, 让处理函数处理
    },
    handleCardClick() {
      this.$bus.$emit("cardClick");
    },
    // 播放音效
    playVoice(voiceUrl, volume = 1) {
      if (this.infoStore.isVolume) {
        var player = new Audio(voiceUrl);
        player.volume = volume; // 设置音量
        player.play(); //播放 mp3这个音频对象
      }
    },
    // 使用卡片的初始通用代码
    startCode(i, isPlay = true, useNum = 0) {
      // 传入卡片索引、是否播放音效以及使用卡片后的剩余使用次数
      if (isPlay) {
        this.playVoice(voice1); // 播放音效
      }
      this.$bus.$emit("clickCardPool", true); // 关闭卡片池窗口
      this.$store.commit("cards/setCardUseNum", { i, useNum }); // 设置卡片使用次数为0
    },
    // 验证当前位置的卡片是否可点击
    isCardClick(curCard) {
      const len = this.infoStore.gameCards.length;
      for (let i = 0; i < len; i++) {
        const card = this.infoStore.gameCards[i];
        if (curCard.cardId === card.cardId) {
          // 选中了自己
          continue;
        }
        // 是否不能点击
        const isUnClick =
          Math.abs(curCard.coor.x - card.coor.x) <= 1 &&
          Math.abs(curCard.coor.y - card.coor.y) <= 1 &&
          curCard.cardId < card.cardId;
        if (isUnClick) {
          console.log("当前卡片无法点击");
          // 如果其他卡片就在'我'附近且cardId大于'我' [位置更高], 则不可点击
          return false;
        }
      }
      return true;
    },
  },
};
</script>

<style lang="less" scoped>
@import "~@/styles/var.less";

.card-icon-container {
  display: flex;
  justify-content: center;
  align-items: center;
  background: @cardBg;
  box-sizing: border-box;
  border: 2px solid @border;
  // 阴影
  box-shadow: 1px 1px 8px rgba(0, 0, 0, 0.15), 3px 3px 4px rgba(0, 0, 0, 0.15);
  &:hover {
    transition: all 0.4s;
    transform: scale(1.04);
  }
  i {
    color: @word;
  }
}
</style>
